package com.hd.boot0407.service.Imp;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hd.boot0407.dao.UserDao;
import com.hd.boot0407.entity.User;
import com.hd.boot0407.service.UserService;
import com.hd.boot0407.util.MyCache;
import com.hd.boot0407.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.apache.commons.io.FilenameUtils;
import cn.hutool.crypto.digest.DigestUtil;

import java.io.*;
import java.util.*;
@Slf4j
@Service
public class UserServiceImp implements UserService {
    @Autowired
    UserDao userDao;
    @Value("${file.upload.path}")
    String fileuploadpath;
    @Value("${file.export.path}")
    String fileExportPath;

    @Override
    public ArrayList<User> getByFileName(String FileName) {
        return userDao.getByFileName(FileName);
    }
    @Override
    public User getById(Integer id) {
        return userDao.getById(id);
    }
    @Override
    public User getByName(String name) {
        if (name != null) {
            return userDao.getByName(name);
        } else {
            final User user = new User();
            user.setName(null);
            return user;
        }
    }

    @Override
    public int DeleteById(Integer id) {
        return userDao.DeleteById(id);
    }

    @Override
    public int DeleteByIdArr(Integer[] id) {
        return userDao.DeleteByIdArr(id);
    }

    @Override
    public Integer addAutoIdUser(User user) {
        return userDao.addAutoIdUser(user);
    }

    @Override
    public Integer updateUser(User user) {
        return userDao.updateUser(user);
    }

    public PageInfo<User> selectAll(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userDao.selectAllUser();
        System.out.println(users);
        return new PageInfo<>(users);
    }
    //对于查询添加如下注解
    @Transactional(propagation = Propagation.SUPPORTS)
    public  User login(String username, String password) {
        log.debug("入参为:username={}.password={}" , username, password) ;
        //根据用户名查询用户,如果查不到用户数据，网直接返回null
        User user = userDao.getByName(username);
        log.debug("入参为:user={}",user);
        /*密码加密处理*/
        final String md5password = DigestUtil.md5Hex(password);
        if (user == null) {
            log.debug("用户名不存在");
            return null;
        }
        //2.比对密码，郊果密码错误，返回null，否网返回user对象
        final String dbpassword = user.getPassword();
        if (dbpassword.equals(md5password)) {
            log.debug("用户密码匹配成功");
            return user;
        }
        log.debug("密码错误");
        return null;
    }
    @Transactional(rollbackFor = Exception.class)  // 当该方法出现异常（ Exception.class）时，会让数据库回滚事务
    @Override
    public void regist(UserVo userVo) throws Exception {
        //1. 把用户上传的头像文件存到指定目录下
        final MultipartFile pic = userVo.getFile1();
        // 获取用户上传文件的原始文件名
        final String originalFilename = pic.getOriginalFilename();
        /*生成随机数*/
        final String randomName = UUID.randomUUID().toString().substring(0,8);
        /*获取文件名后缀*/
        final String extension = FilenameUtils.getExtension(originalFilename);
        String finalFileName = randomName+"."+ extension;
        // 上传文件的路径
        String filepath = fileuploadpath + originalFilename;
        pic.transferTo(new File(finalFileName));
        log.debug("用户头像上传位置,filepath={}", filepath);

        //2. 把用户提交的注册信息写入数据库中
        final User user = new User();
        BeanUtils.copyProperties(userVo, user);

        //3. 处理密码
        final String oldpassword = userVo.getPassword();
        final String md5password = DigestUtil.md5Hex(oldpassword);
        user.setPassword(md5password);

        //4. 设置其他属性
        user.setRegistTime(new Date(System.currentTimeMillis()));
        user.setFilename(originalFilename);
        userDao.addAutoIdUser(user);

    }
    /*老师的*/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String draw(boolean fair) {

        String username = null;

        if (fair){  // 公平抽奖
            // 从数据库中查询所有未中奖的用户信息
            List<User> userList = userDao.getUsersByStatus();
            // 随机选中一个用户
            if (userList!=null&&userList.size()>0){
                final Random random = new Random();
                final int index = random.nextInt(userList.size());
                final User user = userList.get(index); // 中奖用户
                username = user.getName();
                // 更新已经中奖的用户的 状态字段
                userDao.updateStatusById(user.getId());
            }else {
                username = "本轮抽奖已经结束，请重置";
            }

        }else {
            List<User> userList = userDao.getAllUsers();
            if (userList!=null&&userList.size()>0){
                final Random random = new Random();
                final int index = random.nextInt(userList.size());
                final User user = userList.get(index); // 中奖用户
                username = user.getName();
            }else {
                username = "数据库中没有任何用户";
            }
        }

        return username;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void reset() {
        userDao.resetStatus();
    }


    @Override
    public String cacheDraw(boolean fair) {

        String username = null;
        // 判断 MyCache中是否有数据
        if (MyCache.cacheList.size()==0){
            // 从数据库中加载数据到 本地缓存
            final List<User> allUsers = userDao.getAllUsers();
            MyCache.cacheList = allUsers;
        }

        if (fair){
            // 需要从缓存中获取所有 status = 0 的 user数据
            final ArrayList<User> userList = new ArrayList<>();
            for (User user : MyCache.cacheList) {
                if (user.getStatus().equals("0")) {
                    userList.add(user);
                }
            }

//            List<User> list = MyCache.cacheList.stream().filter(user -> user.getStatus().equals("0")).collect(Collectors.toList());


            // 随机选中一个用户
            if (userList!=null&&userList.size()>0){
                final Random random = new Random();
                final int index = random.nextInt(userList.size());
                final User user = userList.get(index); // 中奖用户
                username = user.getName();
                // 更新已经中奖的用户的 状态字段
                for (User user1 : MyCache.cacheList) {
                    if (user1.getId().equals(user.getId())) {
                        user1.setStatus("1");
                    }
                }
            }else {
                username = "本轮抽奖已经结束，请重置";
            }

        }else {
            List<User> userList = MyCache.cacheList;
            if (userList!=null&&userList.size()>0){
                final Random random = new Random();
                final int index = random.nextInt(userList.size());
                final User user = userList.get(index); // 中奖用户
                username = user.getName();
            }else {
                username = "数据库中没有任何用户";
            }
        }

        return username;
    }

    @Override
    public Integer getTotalCount() {
        return userDao.getTotalCount();
    }

    @Override
    public List<User> getallByPage(Integer page, Integer limit) {
        // 根据分页条件，计算mysql的起始行号
        Integer startline = (page - 1) * limit;

        return  userDao.getallByPage(startline,limit);
    }

    @Override
    public PageInfo<User> getallByPageHelpler(Integer page, Integer limit) {

        PageHelper.startPage(page,limit);
        List<User> data = userDao.getAllUsers();

        return new PageInfo<User>(data);
    }

    @Override
    public PageInfo<User> getallByPageHelpler(Integer page, Integer limit, String username, String sex, Date birthday) {
        /*Integer sexInt = null;
        if (sex!=null && !sex.equals("")){
            sexInt = Integer.valueOf(sex);
        }
*/
        PageHelper.startPage(page,limit);
        List<User> data = userDao.getAllUsersByCondition(username,sex,birthday);

        return new PageInfo<User>(data);
    }

    @Override
    public Integer addUser(User user) {
        return userDao.addUser(user);
    }

    @Override
    public String export() throws IOException {
        //查询所有用户数织得到一个list<User>
        List<User> allUsers = userDao.getAllUsers();
        //将List<User>写入指定文件,约定文件格式为csv《逗号分隔的文本文件>
        String filename=UUID.randomUUID().toString().replaceAll("-","")+".csv";
        String filePath=fileExportPath+filename;
        //写入文件对象
        BufferedWriter bw = new BufferedWriter(new FileWriter(filePath));
        for (User user : allUsers) {
            //user --> CSV line(1,mayun,1,99999,......)
            String csvline=user.toCSVString();
            bw.write(csvline);
            bw.newLine();
        }
        bw.flush();
        bw.close();
        return filename;
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void batchInsert(MultipartFile file) throws Exception {
        InputStream is=file.getInputStream();
        BufferedReader br=new BufferedReader(new InputStreamReader(is));
        String line=null;
        ArrayList<User> users = new ArrayList<>();
        while((line= br.readLine())!=null){
            /*csv字符串----》user对象*/
            User user=User.creatUserfromCsvString(line);
            users.add(user);
        }
        br.close();
    }
}
